/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dirstat;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 *
 * @author felipe
 */
public class Dirstat {
    
    private static final String separator = "-";
    
    private static File directoryToSweep;
    private static Map<File, Long> directories = new HashMap<File, Long>();
    private static Long totalSize = 0l;
    private static int maxFileNameLength = 0;
    
    
    public static void main(String args[]) throws IOException {
        
        long start = System.currentTimeMillis();
        
        // Contrôle des paramètres
        if( args.length != 1 || !args[0].startsWith(separator) || args[0].length() < 2) {
            
            System.err.println( "Use dirstat - directory");
            System.exit( 0);
            
        }
        
        
        // Contrôle du répertoire
        directoryToSweep = new File( args[0].substring(1, args[0].length()));
        if( !directoryToSweep.exists() || !directoryToSweep.isDirectory()) {
            
            System.err.println( "Unable to find " + args[1]);
            System.exit( 0);
            
        }
        
        
        // Parcour de l'ensemble des fichiers
        directories.put( directoryToSweep, 0l);
        maxFileNameLength = directoryToSweep.getAbsolutePath().length();
        for(File file : directoryToSweep.listFiles()) {
            
            if( !file.canRead())
                continue;
            
            
            if( file.isFile() || isSymlink(file)) {
                
                directories.put( directoryToSweep, (directories.get( directoryToSweep) + file.length()));
                
            } else {
                
                if( file.getCanonicalPath().length() > maxFileNameLength) {
                
                    maxFileNameLength = file.getAbsolutePath().length();
                
                }
                
                directories.put( file, getDirectorySize( file));
                totalSize += directories.get( file);
                
            }
            
        }
        totalSize += directories.get( directoryToSweep);
        
        
        // Affichage du résultat
        SortedMap<File, Long> sortedMap = new TreeMap<File, Long>( new DirectoryComparator( directories));
        sortedMap.putAll( directories);
        for(File key : sortedMap.keySet()) {
            
            System.out.println( displayFileName(key) + " : " + displaySize( directories.get( key)));
            
        }
        
        long stop = System.currentTimeMillis();
        
        System.out.println( "Taille totale du répertoire : " + displaySize( totalSize));
        System.out.println( "\nTemps d'exécution : " + (stop - start) + "ms");
        
    }
    
    
    /**
     * Va permettre de parcourir l'ensemble des répertoires et sous-répertoires
     * 
     * @param directory
     * @return
     * @throws IOException 
     */
    private synchronized static Long getDirectorySize( File directory) throws IOException {
        
        Long size = 0l;
        
        for( File file : directory.listFiles()) {
            
            if( !file.canRead())
                continue;
            
            if( file.isFile() || isSymlink(file)) {
                
                size += file.length();
                
            } else {
                
                size += getDirectorySize( file);
                
            }
            
        }
        
        return size;
    }
    
    
    /**
     * Permet de déterminer si il s'agit d'un lien symbolique
     * 
     * @param file
     * @return 
     */
    private static boolean isSymlink(File file) {
        
        boolean isSymlink = false;
        
        try {
            
            
            if( file.canRead() && !file.getAbsolutePath().equals( file.getCanonicalPath())) {
                
                isSymlink = true;
                
            }
            
            
        } catch (IOException ex) {
            
            //Logger.getLogger(Dirstat.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
            
        }
        
        return isSymlink;
        
    }
    
    
    
    /**
     * Gestion de l'affichage de la taille des dossiers
     * 
     * @param size
     * @return 
     */
    private static String displaySize( Long size) {
        
        StringBuilder result    = new StringBuilder();
        Double doubleSize       = new Double( size.doubleValue());        
        String[] sizes          = {"o", "Ko", "Mo", "Go"};
        int index               = 0;
        
        
        while ( doubleSize > 1024 && index < 3) {
            
            doubleSize = doubleSize/1024;
            index++;
            
        }
        
        
        result.append( new DecimalFormat("0.00").format( doubleSize)).append(" ").append( sizes[index]);
        
        return result.toString();
        
    }
    
    
    /**
     * 
     * @param directories
     * @return 
     */
    private static String displayFileName( File file) {
        
        StringBuilder result = new StringBuilder( file.getAbsolutePath());
        
        while( result.length() < maxFileNameLength) {
            
            result.append(" ");
            
        }
        
        return result.toString();
        
    }
    
}
